<template>
  <div>
    <el-form :inline="true">
      <el-form-item>
        <el-input placeholder="帐户代码" v-model="searchDto.userName" auto-complete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-select v-model="searchDto.profession" clearable placeholder="请选择工种">
          <el-option
            v-for="item in professionOptions"
            :key="item.id"
            :label="item.name"
            :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-select v-model="searchDto.roleId" clearable placeholder="请选择角色">
          <el-option
            v-for="item in roleInfo"
            :key="item.roleId"
            :label="item.displayName"
            :value="item.roleId">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="fuzzyQuery()">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleAdd">新增</el-button>
      </el-form-item>
      <el-dropdown @command="handleCommand">
        <el-button type="primary">导入<i class="el-icon-arrow-down el-icon--right"></i>
        </el-button>
        <el-dropdown-menu slot="dropdown">
          <a href="/static/账户导入模板.xlsx" download="账户导入模板.xlsx"
             style="color:#5a5e66;text-decoration: none ">
            <el-dropdown-item command="handleDownload">模板下载
            </el-dropdown-item>
          </a>
          <el-dropdown-item command="handleImport">数据导入</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <el-form-item>
        <el-button type="primary" @click="excelExport">数据导出</el-button>
      </el-form-item>
    </el-form>
    <!-- 账户一览 -->
    <custom-table
      :columns="columns"
      :data="accountList"
      :tableLoadingFlag="tableLoadingFlag"
      :operationColumn="operationColumn"
      :pagination="pagination">
    </custom-table>

    <!-- 账户模板导入模态框 -->
    <el-dialog title="模板导入" :visible.sync="uploadVisible"
               :close-on-click-modal="false" :before-close="uploadCancel">
      <div>
        <el-form label-width="80px" ref="uploadForm" :inline="true">
          <el-form-item style="padding-left: 120px">
            <el-upload
              class="upload-demo"
              :action="uploadUrl"
              :headers="myHeaders"
              name="file"
              :on-error="uploadError"
              :on-success="uploadSuccess"
              :before-upload="beforeAvatarUpload"
              multiple
              drag
              :limit="1"
              :file-list="fileList">
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em><br/>只能上传xlsx文件，且不超过10M</div>
            </el-upload>
          </el-form-item>
          <!--显示导入中错误的数据-->
          <div style="height: 200px;overflow-y: auto" v-if="hideTable">
            <custom-table
              :data="wrongDataList"
              :columns="detailColumns">
            </custom-table>
          </div>
        </el-form>
      </div>
      <div slot="footer">
        <el-button type="primary" @click="uploadCancel()">确定</el-button>
      </div>
    </el-dialog>
    <!-- 账号新增修改模态框 -->
    <el-dialog :title="dialogType ==='add'? '新增账号':'账号信息修改'" :visible.sync="dialogVisible"
               :close-on-click-modal="false">
      <el-form :rules="accountRules" :model="accountDto" label-width="80px" ref="accountForm">
        <el-form-item label="帐户代码" prop="userName">
          <el-input v-model="accountDto.userName" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="用户姓名" prop="name">
          <el-input v-model="accountDto.name" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="帐户密码" prop="password" v-if="dialogType ==='add'">
          <el-input type="password" v-model="accountDto.password" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="工种" prop="profession">
          <el-select v-model="accountDto.profession" placeholder="请选择工种">
            <el-option
              v-for="item in professionOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="accountDto.email" clearable placeholder="service@winsound.com.cn,scb001@winsound.com.cn"
                    auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="电话" prop="tel">
          <el-input v-model="accountDto.tel" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="所在地区">
          <el-row>
            <el-col :span="8" prop="provinceRule">
              <el-select v-model="accountDto.provinceCode" clearable placeholder="请选择省份" @change="getCity()">
                <el-option
                  v-for="item in allProvince"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code">
                </el-option>
              </el-select>
            </el-col>
            <el-col :span="8" prop="cityRule">
              <el-select v-model="accountDto.cityCode" clearable placeholder="请选择城市" @change="getArea()">
                <el-option
                  v-for="item in allCityInfo"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code">
                </el-option>
              </el-select>
            </el-col>
            <el-col :span="8" prop="areaRule">
              <el-select v-model="accountDto.areaCode" clearable placeholder="请选择地区">
                <el-option
                  v-for="item in allAreaInfo"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code">
                </el-option>
              </el-select>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="详细地址" prop="address">
          <el-input v-model="accountDto.address" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="cancel('accountForm')">取消</el-button>
        <el-button type="primary" @click="submit()">确定</el-button>
      </div>
    </el-dialog>
    <!-- 给账号分配角色模态框 -->
    <el-dialog title="分配角色" :visible.sync="accountRoleDialogVisible" :close-on-click-modal="false">
      <el-form label-position="top" label-width="80px" ref="accountRoleForm">
        <el-form-item label="请选择">
          <el-checkbox-group v-model="accountRoles">
            <el-checkbox
              v-for="role in roleList"
              :key="role.id"
              :label="role.id">{{role.displayName}}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="cancel('accountRoleForm')">取消</el-button>
        <el-button type="primary" @click="roleSubmit()" v-no-more-click>确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import CustomTable from '@/components/table/CustomTable'
  import store from '@/store'
  import {
    apiGetAccountList,
    apiAddAccount,
    apiDelAccount,
    apiRoleAccount,
    apiEnableAccount,
    apiDisableAccount,
    apiGetRoleInfo,
    apiGetRoleIdList,
    apiExport,
    apiUpdUser,
    apiGetUserById
  } from '@/api/basic/account'
  import {apiGetRoleList} from '@/api/basic/role'
  import {getUserId} from '@/utils/token'
  import {parseTime} from '@/utils'
  import {apiUserReadExcel} from '@/api/excel/excelRead'
  import {baseInfo} from '@/utils/fetch'
  import {apiGetCity, apiGetArea} from '@/api/dictionary'
  import {encrypt} from "../../utils/encrypt";
  import {downloadExcel} from "../../utils";

  export default {
    name: 'account',
    components: {
      CustomTable
    },
    created () {
      let listQuery = {
        pageNumber: this.pagination.currentPage,
        pageSize: this.pagination.pageSize
      }
      this.getAccountList(listQuery)
      let query = {
        userId: getUserId()
      }
      this.getRoleTypeList(query)
      this.getAllProvince()
    },
    data () {
      return {
        uploadUrl: baseInfo() + '/api/v1/upload',
        myHeaders: {'access_token': store.getters.token},
        // 上传文件显示
        fileList: [],
        // 文件上传路径
        importFileUrl: baseInfo() + '/api/v1/upload',
        // 文件上传参数
        upLoadData: {},
        listQuery: {
          id: '',
          flag: '',
          userName: '',
          profession: undefined,
          roleId: ''
        },
        // 所有省份
        allProvince: [],
        // 所有城市
        allCityInfo: [],
        // 所有地区
        allAreaInfo: [],
        selectedUserId: -1,
        accountRoles: [],                             // 账号增删模态框相关数据
        roleList: [],
        roleInfo: [],
        wrongDataList: [],
        uploadVisible: false,
        hideTable: false,
        dialogVisible: false,
        accountRoleDialogVisible: false,
        professionOptions: this.getCustomerProfessionTypeList(),    // 工种列表
        userIdDto: {
          userId: ''
        },
        searchDto: {
          userName: '',
          profession: undefined,
          roleId: ''
        },
        dialogType: '',
        accountDto: {
          userId: undefined,
          userName: '',
          name: '',
          password: '',
          email: '',
          tel: '',
          profession: undefined,
          professionId: '',
          provinceCode: '',
          cityCode: '',
          areaCode: '',
          address: '',
          province: '',
          city: '',
          area: ''
        },
        accountRules: {
          userName: [
            {required: true, message: '请输入帐户代码', trigger: 'blur'},
            {min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur'}
          ],
          name: [
            {required: true, message: '请输入用户姓名', trigger: 'blur'},
            {max: 20, message: '长度不超过 20 个字符', trigger: 'blur'}
          ],
          password: [
            {required: true, message: '请输入密码', trigger: 'blur'},
            {
              pattern: /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$).{6,20}$/,
              message: '密码包含 数字,英文,字符中的两种以上，长度6-20',
              trigger: 'blur'
            }
          ],
          profession: [
            {required: true, message: '请选择工种', trigger: 'blur'}
          ],
          email: [
            {required: true, message: '请输入邮箱', trigger: 'blur'},
            {max: 100, message: '长度不超过100个字符', trigger: 'blur'}
          ],
          tel: [
            {required: true, message: '请输入手机号', trigger: 'blur'}
          ],
          address: [
            {required: true, message: '请输入详细地址', trigger: 'blur'},
            {max: 255, message: '长度不超过 255 个字符', trigger: 'blur'}
          ],
          provinceRule: [
            {required: true, message: '请选择省份', trigger: 'change'}
          ],
          cityRule: [
            {required: true, message: '请选择城市', trigger: 'change'}
          ],
          areaRule: [
            {required: true, message: '请选择地区', trigger: 'change'}
          ]
        },
        tableLoadingFlag: false,               // 账户一览相关数据
        accountList: [],
        columns: [
          {label: 'ID', name: 'id', width: '80', align: 'center'},
          {label: '帐户代码', name: 'userName', align: 'center'},
          {label: '用户姓名', name: 'name', align: 'center'},
          {label: '工种', name: 'profession', align: 'center'},
          {label: '状态', name: 'accountStatus', align: 'center'},
          {label: '最后登陆时间', name: 'loginTime', width: '180', align: 'center', formatter: this.formatTime}
        ],
        detailColumns: [
          {label: '错误行号', name: 'wrongRowNO', width: '77', height: '40', align: 'center'},
          {label: '错误原因', name: 'reason', width: '120', height: '40', align: 'center'},
          {label: '帐户代码', name: 'userName', width: '80', height: '40', align: 'center'},
          {label: '用户姓名', name: 'name', width: '80', height: '40', align: 'center'},
          {label: '密码', name: 'password', width: '80', height: '40', align: 'center'},
          {label: '邮箱', name: 'email', width: '80', height: '40', align: 'center'},
          {label: '联系电话', name: 'tel', width: '80', height: '40', align: 'center'},
          {label: '工种', name: 'profession', width: '80', height: '40', align: 'center'},
          {label: '省份', name: 'province', width: '80', height: '40', align: 'center'},
          {label: '城市', name: 'city', width: '80', height: '40', align: 'center'},
          {label: '地区', name: 'area', width: '80', height: '40', align: 'center'},
          {label: '详细地址', name: 'address', width: '80', height: '40', align: 'center'}
        ],
        operationColumn: {
          width: '180',
          operations: [
            {name: '分配角色', callback: this.handleRole},
            {name: '编辑', callback: this.handleEdit},
            {name: '删除', callback: this.handleDel},
            {name: '启用', callback: this.handleEnable, page: 'enable'},
            {name: '禁用', callback: this.handleDisable, page: 'enable'}
          ]
        },
        pagination: this.getData(this.getAccountList)
      }
    },
    methods: {
      excelExport () {
        let paramsPost = {
          userId: getUserId(),
          userName: this.searchDto.userName,
          profession: this.searchDto.profession,
          roleId: this.searchDto.roleId
        }
        apiExport(paramsPost).then(response => {
          downloadExcel(response.data, '自有售后用户信息导出表')
        }).catch(err => {
          console.log(err)
        })
      },
      handleCommand (command) {
        if (command === 'handleImport') {
          this.dialogType = 'upload'
          this.uploadVisible = true
        } else if (command === 'handleDownload') {
        }
      },
      uploadCancel () {
        this.uploadVisible = false
        this.wrongDataList = []
        this.fileList = []
        this.hideTable = false
        this.$refs['uploadForm'].resetFields()
      },
      // 上传成功后的回调
      uploadSuccess (response, file, fileList) {
        this.$message({
          showClose: true,
          message: '上传文件成功！'
        })
        let filePath = response.data
        this.excelRead(filePath)
      },
      // 上传错误
      uploadError (err, file, fileList) {
        this.$message({
          showClose: true,
          message: '上传失败，请重试！'
        })
      },
      // 上传前对文件的大小的判断
      beforeAvatarUpload (file) {
        const extension = file.name.split('.')[1] === 'xlsx'
        const isLt2M = file.size / 1024 / 1024 < 10
        if (!extension) {
          this.$message({
            showClose: true,
            message: '上传模板只能是 xlsx 格式!'
          })
        }
        if (!isLt2M) {
          this.$message({
            showClose: true,
            message: '上传模板大小不能超过 10MB!'
          })
        }
        return extension && isLt2M
      },
      getAllProvince () {
        apiGetCity().then(response => {
          this.allProvince = response.data
        })
      },
      getCity () {
        this.accountDto.cityCode = ''
        if (this.accountDto.provinceCode === '') {
          this.allCityInfo = []
        }
        let listQuery = {
          province: this.accountDto.provinceCode
        }
        apiGetCity(listQuery).then(response => {
          this.allCityInfo = response.data
        })
      },
      getArea () {
        this.accountDto.areaCode = ''
        if (this.accountDto.cityCode === '') {
          this.allAreaInfo = []
        }
        let listQuery = {
          city: this.accountDto.cityCode
        }
        apiGetArea(listQuery).then(response => {
          this.allAreaInfo = response.data
        })
      },
      getRoleTypeList (query) {
        query.userId = getUserId()
        apiGetRoleInfo(query).then(response => {
          this.roleInfo = response.data
        })
      },
      formatTime (row, column, cellValue) {
        return parseTime(cellValue)
      },
      onSelected (data) {             // 省市区联动回调
        this.accountDto.provinceCode = data.province.code
        this.accountDto.cityCode = data.city.code
        this.accountDto.areaCode = data.area.code

        this.accountDto.province = data.province.value
        this.accountDto.city = data.city.value
        this.accountDto.area = data.area.value
      },
      getAccountList (listQuery) {
        this.tableLoadingFlag = true
        if (this.searchDto.userName !== '') {
          listQuery.userName = this.searchDto.userName
        }
        if (this.searchDto.profession !== undefined) {
          listQuery.profession = this.searchDto.profession
        }
        if (this.searchDto.roleId !== '') {
          listQuery.roleId = this.searchDto.roleId
        }
        apiGetAccountList(listQuery).then(response => {
          this.accountList = response.data
          this.pagination.totalRecords = response.totalRecords
          this.tableLoadingFlag = false
        }).catch(() => {
          this.tableLoadingFlag = false
        })
      },
      handleAdd () {
        if (this.$refs['accountForm']) {
          this.accountDto = {
            userId: undefined,
            userName: '',
            name: '',
            password: '',
            email: '',
            tel: '',
            profession: undefined,
            provinceCode: '',
            cityCode: '',
            areaCode: '',
            address: '',
            province: '',
            city: '',
            area: ''
          }
          this.$refs['accountForm'].resetFields()
        }
        this.dialogType = 'add'
        this.dialogVisible = true
      },
      handleEdit (row) {
        apiGetUserById(row.id).then(response => {
          this.accountDto.provinceCode = response.data.provinceCode
          this.getCity()
          this.accountDto.cityCode = response.data.cityCode
          this.getArea()
          this.accountDto = response.data
          this.accountDto.userId = row.id
          this.accountDto.profession = this.accountDto.professionId
          this.dialogType = 'edit'
          this.dialogVisible = true
        })
      },
      handleEnable (row) {
        this.$confirm('确定启用该账号?', '账号启用', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.userIdDto.userId = row.id
          apiEnableAccount(this.userIdDto).then(() => {
            this.$message({
              showClose: true,
              type: 'success',
              message: '启用成功!'
            })
            this.getAccountList({
              pageNumber: this.pagination.currentPage,
              pageSize: this.pagination.pageSize
            })
          })
        }).catch(() => {
        })
      },
      handleDisable (row) {
        this.$confirm('确定禁用该账号?', '账号禁用', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.userIdDto.userId = row.id
          apiDisableAccount(this.userIdDto).then(() => {
            this.$message({
              showClose: true,
              type: 'success',
              message: '禁用成功!'
            })
            this.getAccountList({
              pageNumber: this.pagination.currentPage,
              pageSize: this.pagination.pageSize
            })
          })
        }).catch(() => {
        })
      },
      handleDel (row) {
        this.$confirm('确定删除该账号?', '账号删除', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$confirm('是否删除该账号的子账号', '子账号删除', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.listQuery.flag = 0
            this.listQuery.id = row.id
            apiDelAccount(this.listQuery).then(() => {
              this.$message({
                showClose: true,
                type: 'success',
                message: '删除成功!'
              })
              this.getAccountList({
                pageNumber: this.pagination.currentPage,
                pageSize: this.pagination.pageSize
              })
            })
          }).catch(() => {
            this.listQuery.flag = 1
            this.listQuery.id = row.id
            apiDelAccount(this.listQuery).then(() => {
              this.$message({
                showClose: true,
                type: 'success',
                message: '删除成功!'
              })
              this.getAccountList({
                pageNumber: this.pagination.currentPage,
                pageSize: this.pagination.pageSize
              })
            })
          })
        })
      },
      fuzzyQuery () {
        apiGetAccountList(this.searchDto).then(response => {
          this.accountList = response.data
          this.pagination.totalRecords = response.totalRecords
          this.tableLoadingFlag = false
        }).catch(() => {
          this.tableLoadingFlag = false
        })
      },
      excelRead (filePath) {
        apiUserReadExcel(filePath).then(response => {
          if (response.data) {
            this.wrongDataList = response.data
            this.hideTable = true
          } else {
            this.$message({
              showClose: true,
              message: '导入执行中，请稍后',
              type: 'success'
            })
            this.hideTable = false
            this.getAccountList({
              pageNumber: this.pagination.currentPage,
              pageSize: this.pagination.pageSize
            })
          }
          this.fileList = []
        })
      },
      submit () {
        this.$refs['accountForm'].validate((valid) => {
          if (valid) {
            if (this.dialogType === 'add') {
              this.addSubmit()
            } else {
              this.updSubmit()
            }
          } else {
            return false
          }
        })
      },
      addSubmit () {
        let dto = {
          userId: this.accountDto.userId,
          userName: this.accountDto.userName,
          name: this.accountDto.name,
          password: this.accountDto.password,
          email: this.accountDto.email,
          tel: this.accountDto.tel,
          profession: this.accountDto.profession,
          professionId: this.accountDto.professionId,
          provinceCode: this.accountDto.provinceCode,
          cityCode: this.accountDto.cityCode,
          areaCode: this.accountDto.areaCode,
          address: this.accountDto.address,
          province: this.accountDto.province,
          city: this.accountDto.city,
          area: this.accountDto.area
        }
        dto.password = encrypt(dto.password)
        apiAddAccount(dto).then(() => {
          this.$message({
            showClose: true,
            message: '新增成功',
            type: 'success'
          })
          this.dialogVisible = false
          let listQuery = {
            pageNumber: this.pagination.currentPage,
            pageSize: this.pagination.pageSize
          }
          this.getAccountList(listQuery)
        })
      },
      updSubmit () {
        let dto = {
          userId: this.accountDto.userId,
          userName: this.accountDto.userName,
          name: this.accountDto.name,
          password: this.accountDto.password,
          email: this.accountDto.email,
          tel: this.accountDto.tel,
          profession: this.accountDto.profession,
          professionId: this.accountDto.professionId,
          provinceCode: this.accountDto.provinceCode,
          cityCode: this.accountDto.cityCode,
          areaCode: this.accountDto.areaCode,
          address: this.accountDto.address,
          province: this.accountDto.province,
          city: this.accountDto.city,
          area: this.accountDto.area
        }
        dto.password = encrypt(dto.password)
        apiUpdUser(dto).then(() => {
          this.$message({
            showClose: true,
            message: '更新成功',
            type: 'success'
          })
          this.dialogVisible = false
          let listQuery = {
            pageNumber: this.pagination.currentPage,
            pageSize: this.pagination.pageSize
          }
          this.getAccountList(listQuery)
        })
      },
      handleRole (row) {
        this.accountRoles = []
        this.selectedUserId = row.id
        this.accountRoleDialogVisible = true
        let listQuery = {
          userId: row.id
        }
        apiGetRoleIdList(listQuery).then(response => {
          for (let i in response.data) {
            var flags = response.data[i].roleId
            this.accountRoles.push(flags)
          }
        })
        let flagDto = {
          flag: 0
        }
        apiGetRoleList(flagDto).then(response => {
          this.roleList = response.data
        })
      },
      roleSubmit () {
        let data = {
          userId: this.selectedUserId,
          roleIdString: this.accountRoles.join(',').toString()
        }
        if (!data.roleIdString) {
          this.$message({
            showClose: true,
            message: '未选择角色',
            type: 'error'
          })
        } else {
          apiRoleAccount(data).then(() => {
            this.$message({
              showClose: true,
              message: '新增成功',
              type: 'success'
            })
            this.cancel('accountRoleForm')
          })
        }
      },
      cancel (formName) {
        this.dialogVisible = false
        this.accountRoleDialogVisible = false
        this.$refs[formName].resetFields()
      }
    }
  }
</script>
